package gm.commands;

import com.martiansoftware.jsap.JSAP;
import com.martiansoftware.jsap.JSAPException;
import com.martiansoftware.jsap.JSAPResult;
import com.martiansoftware.jsap.UnflaggedOption;
import gm.GmLog;
import gm.server.Server;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

/**
 * Alap parancsok tárolója.
 *
 * @author imruf84
 */
public class StandardCommands extends CommandSet {

    /**
     * Konstruktor.
     *
     * @param server szerver
     */
    public StandardCommands(Server server) {
        super(server);
    }

    @Override
    protected void createCommands() {
        try {
            hello();
            help();
            doSQL();
        } catch (JSAPException ex) {
            GmLog.printError(ex);
        }
    }

    /**
     * Helló parancs létrehozása.
     */
    private void hello() {

        Command c = new Command("hello", (final Command command, final String sCommand, final JSAPResult result, final PrintWriter out) -> "Hello world!");

        c.setHelp("Print \"Hello world!\".");

        put(c.getName(), c);
    }

    /**
     * Help parancs létrehozása.
     */
    private void help() {

        Command c = new Command("help", (final Command command, final String sCommand, final JSAPResult result, final PrintWriter out) -> "Commands:" + getServer().getCommandsList());

        c.setHelp("Print the avaiable commands.");

        put(c.getName(), c);
    }

    /**
     * SQL parancsok közvetlen futtatásának létrehozása.
     *
     * @throws JSAPException kivétel
     */
    private void doSQL() throws JSAPException {

        final String dbName = "database";
        final String sql = "sql";

        Command c = new Command(sql, (final Command command, final String sCommand, final JSAPResult result, final PrintWriter out) -> {
            String vDbName = result.getString(dbName);
            String vSql = result.getString(sql);
            
            try {
                Class.forName("org.h2.Driver");
                
                try (
                        Connection connection = DriverManager.getConnection("jdbc:h2:./" + vDbName + ";trace_level_file=0;AUTO_SERVER=TRUE", "sa", "");
                        Statement stat = connection.createStatement();
                        ResultSet rs = stat.executeQuery(vSql)) {
                    
                    String s = "";
                    
                    while (rs.next()) {
                        s += rs.getMetaData().toString();
                    }

                    return s;
                    
                } catch (SQLException ex) {
                    return ex.getLocalizedMessage();
                }
            } catch (ClassNotFoundException ex) {
                return ex.getLocalizedMessage();
            }
        });

        UnflaggedOption pDbName = new UnflaggedOption(dbName)
                .setStringParser(JSAP.STRING_PARSER)
                .setRequired(true)
                .setGreedy(false);
        c.setHelp("Database name to connect.");
        c.registerParameter(pDbName);

        UnflaggedOption pSQL = new UnflaggedOption(sql)
                .setStringParser(JSAP.STRING_PARSER)
                .setRequired(true)
                .setGreedy(false);
        c.setHelp("SQL expression.");
        c.registerParameter(pSQL);

        c.setHelp("Run an SQL command.");

        put(c.getName(), c);
    }

}
